package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.pojo.PageResult;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.mapper.*;
import com.leyou.item.pojo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsService {

    @Autowired
    SpuMapper sm;

    @Autowired
    SpuDetailMapper sdm;

    @Autowired
    CategoryMapper cm;

    @Autowired
    BrandMapper bm;

    @Autowired
    SkuMapper skuMapper;
    @Autowired
    StockMapper stockMapper;

    @Autowired
    AmqpTemplate amqpTemplate;

    public PageResult<SpuBo> querySpu(String key, Boolean saleable, Integer page, Integer rows) {

        PageHelper.startPage(page,rows);

        // 1.根据key进行搜索
        Example example = new Example(Spu.class);
        // where条件
        Example.Criteria criteria = example.createCriteria();

        // 2.根据key进行模糊查询  排除空格之后判断是否为空
        if(StringUtils.isNotBlank(key)){
            criteria.andLike("title","%"+key+"%");
        }

        // 3.上架下架的问题  根据saleable进行判断
        if(saleable != null){
            // 1  true  0  false
            criteria.andEqualTo("saleable",saleable);
        }

        // 分页，模糊查询，上架下架
        List<Spu> spus = sm.selectByExample(example);
        // spus spu对象没有cname和bname
        // 还得进行新一轮的查询，从spu对象中得到cid1，cid2，cid3  brand_id
        PageInfo<Spu> pages = new PageInfo<>(spus);

        List<SpuBo> spuBos = new ArrayList<>();
//        spus.stream().map()
        spus.forEach(s->{
//            String cid1Name = cm.selectByPrimaryKey(s.getCid1()).getName();
//            String cid2Name = cm.selectByPrimaryKey(s.getCid2()).getName();
//            String cid3Name = cm.selectByPrimaryKey(s.getCid3()).getName();
//            String cname = cid1Name+"/"+cid2Name+"/"+cid3Name;
            // 通过Arrays工具类对象，可以将多个值，直接转化成集合对象
            List<Category> categories = cm.selectByIdList(Arrays.asList(s.getCid1(), s.getCid2(), s.getCid3()));

            // 结合对象  category.getName()集合对象
            // stream 将集合对象，转化成流对象
            // map 循环，里面的值，默认返回
            List<String> collect = categories.stream().map(category -> category.getName()).collect(Collectors.toList());
            // join方法，是属于StringUtils
            // org.apache.commons.lang.StringUtils
            String cname = StringUtils.join(collect,"/");

            String bname = bm.selectByPrimaryKey(s.getBrandId()).getName();

            SpuBo spuBo = new SpuBo();
            // 原来的类的内容，也复制到bo对象中
            BeanUtils.copyProperties(s,spuBo);
            spuBo.setBname(bname);
            spuBo.setCname(cname);

            spuBos.add(spuBo);

        });

        PageResult<SpuBo> pageResult = new PageResult<>();
        pageResult.setItems(spuBos);
        pageResult.setTotal(pages.getTotal());

        return pageResult;
    }

    @Transactional
    public void saveGoods(SpuBo spuBo) {
        // spu  spuDetail   sku  stock库存
        // 多态，参数的多态
        // 1.完善spu对象
        spuBo.setId(null);
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        // 2.插入到spu表中  useGenericKey=true   keyProperties=主键
        sm.insert(spuBo);

        // 3.插入到spuDetail表中
        spuBo.getSpuDetail().setSpuId(spuBo.getId());
        sdm.insert(spuBo.getSpuDetail());

        // 4.插入到sku表中
        insertSkus(spuBo);


        sendMsg("insert" , spuBo.getId());

    }

    public SpuDetail getSpuDetailById(Long id) {
        return sdm.selectByPrimaryKey(id);
    }

    @Transactional
    public List<Sku> getSkusById(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> skus = skuMapper.select(sku);

        // 依次遍历sku对象，并取得对应的id，去到stock表中根据id，查找库存信息
        // 存入到对应的sku对象中
        // 映射对象，映射的就是集合中的对象
        // 临时对象，副本
        skus.forEach(s->{
            Long skuId = s.getId();
            Stock stock = stockMapper.selectByPrimaryKey(skuId);
            Integer stockNum = stock.getStock();
            s.setStock(stockNum);
        });

        return skus;

    }

    @Transactional
    public void editGoods(SpuBo spuBo) {

        // 1.更改最后修改时间
        spuBo.setLastUpdateTime(new Date());
        // 2.更改spu表信息
        sm.updateByPrimaryKey(spuBo);

        // 3.更改到spuDetail表中
        spuBo.getSpuDetail().setSpuId(spuBo.getId());
        sdm.updateByPrimaryKey(spuBo.getSpuDetail());

        // 4.根据spu对象的id，找到之前的老的sku对象们，并将他们都删掉
        Long spuId = spuBo.getId();
        Example example = new Example(Sku.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("spuId",spuId);
        // delete from sku where spu_id=#{spuId};
        skuMapper.deleteByExample(example);


        // 5.插入到sku表中
        insertSkus(spuBo);

        sendMsg("update" , spuBo.getId());

    }

    public void deleteSpu(Long id){
        sm.deleteByPrimaryKey(id);
        sendMsg("delete",id);
    }

    private void sendMsg(String key,Long id) {
        try {
            // 消息的发送
            amqpTemplate.convertAndSend("item."+key, id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void insertSkus(SpuBo spuBo) {
        List<Sku> skus = spuBo.getSkus();
        skus.forEach(s -> {
            s.setSpuId(spuBo.getId());
            s.setId(null);
            s.setCreateTime(spuBo.getCreateTime());
            s.setLastUpdateTime(spuBo.getCreateTime());

            skuMapper.insert(s);

            // 5.插入到库存表 stock表中
            Integer stockNum = s.getStock();
            Stock stock = new Stock();
            stock.setStock(stockNum);
            stock.setSkuId(s.getId());
            stockMapper.insert(stock);

        });
    }

    public Spu getSpuById(Long id) {
        Spu spu = sm.selectByPrimaryKey(id);
        return spu;
    }

    public Sku getSkuByid(Long id) {
        Sku sku = skuMapper.selectByPrimaryKey(id);
        return sku;
    }
}
